home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
public
/
plan
/
src
/
notifier.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
8KB
|
338 lines
/*
* Notify program. Pops up a green, yellow, or red menu with some text
* in it. A title can be specified, default is "Notify". The text is
* read from the argument file name, or from standard input.
*
* This program is intended to be used by the pland daemon. It must
* reside in the same directory as pland; pland looks at its own path
* in argv[0] to locate notifier.
*
* Author: thomas@bitrot.in-berlin.de (Thomas Driemeyer)
*/
#ifndef MIPS
#include <stdlib.h>
#endif
#include <stdio.h>
#ifndef VARARGS
#include <stdarg.h>
#endif
#include <time.h>
#include <Xm/Xm.h>
#include <X11/StringDefs.h>
#include "notifier.h"
#include "version.h"
#include "bm_noticon.h"
#if defined(XlibSpecificationRelease) && defined(sgi)
#include <X11/Xmu/Editres.h>
#define EDITRES
#endif
#ifndef _XEditResCheckMessages
#undef EDITRES
#endif
#ifdef USERAND
#define random rand
#define srandom srand
#endif
static void init_colors(), readfile(), usage();
#ifdef MIPS
extern char *malloc(), *realloc();
#endif
Display *display; /* common server */
GC gc; /* common graphics context */
char *progname; /* argv[0] */
Pixel color[NCOLS]; /* colors: COL_* */
Pixel bkcolor = COL_RED; /* background color (COL_*) */
XtAppContext app; /* application handle */
static Widget toplevel; /* widget tree */
static String fallbacks[] = {
"*background: #a0a0a0",
"*colStd: #202020",
"*colRedAlert: #ff0000",
"*colYellowAlert: #c0a000",
"*colGreenAlert: #20a020",
#ifndef sgi
"*fontList: -*-helvetica-*-r-*-*-17-*",
#else
"*fontList: -b&h-*-medium-r-*-*-17-*",
#endif
"*title.fontList: -*-times-*-*-*-*-34-*",
#ifndef sgi
"*message.fontList: -*-new century schoolbook-*-r-*-*-17-*",
#else
"*message.fontList: -*-palatino-*-r-*-*-17-*",
#endif
#ifdef DESKTOP
"*sgiMode: True",
"*useSchemes: True",
#endif
NULL
};
/*
* initialize everything and create the main calendar window
*/
main(argc, argv)
int argc;
char *argv[];
{
Pixmap icon;
int n, i;
String *p;
char *msg = 0; /* points to ascii message */
char *title = "Notifier";
char *icontitle = "Notify";
long timeout = 0;
char geometry[40];
if ((progname = strrchr(argv[0], '/')) && progname[1])
progname++;
else
progname = argv[0];
srandom(time((void *)0));
sprintf(geometry, "*geometry: +%d+%d", random()*16&240,
random()*16&240);
fallbacks[0] = geometry;
toplevel = XtAppInitialize(&app, title, NULL, 0,
# ifndef XlibSpecificationRelease
(Cardinal *)&argc, argv,
# else
/* X11R5 introduced XlibSpecificationRelease
and made cast unnecessary */
&argc, argv,
# endif
fallbacks, NULL, 0);
# ifdef EDITRES
XtAddEventHandler(toplevel, (EventMask)0, TRUE,
_XEditResCheckMessages, NULL);
# endif
display = XtDisplay(toplevel);
gc = XCreateGC(display, DefaultRootWindow(display), 0, 0);
init_colors();
if (icon = XCreatePixmapFromBitmapData(display,
DefaultRootWindow(display),
icon_bits, icon_width, icon_height,
WhitePixelOfScreen(XtScreen(toplevel)),
BlackPixelOfScreen(XtScreen(toplevel)),
DefaultDepth(display, 0)))
XtVaSetValues(toplevel, XmNiconPixmap, icon, NULL);
for (n=1; n < argc; n++)
if (*argv[n] == '-')
for (i=1; i && argv[n][i]; i++)
switch(argv[n][i]) {
case 'd':
for (p=fallbacks; *p; p++)
printf("%s%s\n", progname, *p);
fflush(stdout);
exit(0);
case 'v':
fprintf(stderr, "%s: %s %s\n",
progname, VERSION, PATCHLEVEL);
exit(0);
case 'e':
timeout = atol(&argv[n][i+1]);
i = -1;
break;
case 't':
title = &argv[n][i+1];
i = -1;
break;
case 'i':
icontitle = &argv[n][i+1];
i = -1;
break;
case '1':
bkcolor = COL_GREEN;
break;
case '2':
bkcolor = COL_YELLOW;
break;
case '3':
bkcolor = COL_RED;
break;
default:
usage();
}
else {
FILE *fp;
if (msg)
usage();
if (!(fp = fopen(argv[n], "r"))) {
fprintf(stderr, "%s: ", progname);
perror(argv[n]);
exit(1);
}
readfile(&msg, fp);
fclose(fp);
}
if (!msg)
readfile(&msg, stdin);
XtVaSetValues(toplevel, XmNiconName, icontitle, NULL);
create_widgets(toplevel, title, msg);
XtRealizeWidget(toplevel);
XBell(display, 0);
XBell(display, 0);
if (timeout)
(void)XtAppAddTimeOut(app, timeout*60*1000,
(XtTimerCallbackProc)exit, 0);
XtAppMainLoop(app);
return(0);
}
/*
* whenever something goes seriously wrong, this routine is called. It makes
* code easier to read. fatal() never returns. This may fail horribly if
* VARARGS is defined, but at least it's going to do *something*.
*/
#ifndef VARARGS
/*VARARGS*/
fatal(char *fmt, ...)
{
va_list parm;
va_start(parm, fmt);
fprintf(stderr, "%s: ", progname);
vfprintf(stderr, fmt, parm);
va_end(parm);
putc('\n', stderr);
exit(1);
}
#else
/*VARARGS*/
fatal(fmt, a, b, c, d)
char *fmt;
int a, b, c, d;
{
fprintf(stderr, fmt, a, b, c, d);
putc('\n', stderr);
exit(1);
}
#endif
/*
* read the message to be displayed in the window from a file (or stdin).
* Allocate enough storage.
* This routine avoids feof() because it seems to be broken on some Unix PCs.
*/
static void readfile(msg, fp)
char **msg;
FILE *fp;
{
long size = 4098; /* msg size, two more for \0 */
long nread = 0; /* how many read so far */
int ncs; /* how many added this time */
if (!(*msg = malloc(size)))
fatal("can't malloc %d bytes for message", size);
for (;;) {
ncs = fread(*msg + nread, 1, 4096, fp);
(*msg)[nread += ncs] = 0;
if (ncs < 4096)
break;
if (!(*msg = realloc(*msg, size += 4096)))
fatal("can't realloc %d bytes for message", size);
}
}
/*
* usage information
*/
static void usage()
{
fprintf(stderr,
"Usage: %s [options] [file]\nOptions:\n%s%s%s%s%s%s%s%s%s",
progname,
"\t-h\t\tprint this help text\n",
"\t-d\t\tdump fallback app-defaults and exit\n",
"\t-tstring\tset title string (quote blanks)\n",
"\t-istring\tset icon title string (quote blanks)\n",
"\t-v\t\tprint version string\n",
"\t-eN\t\texpire after N minutes\n",
"\t-1\t\tprint green window\n",
"\t-2\t\tprint yellow window\n",
"\t-3\t\tprint red window\n");
exit(1);
}
/*
* read real application resources
*/
static char *string_resource(res_name, res_class_name)
char *res_name;
char *res_class_name;
{
char *res;
XtResource res_list[1];
res_list->resource_name = res_name;
res_list->resource_class = res_class_name;
res_list->resource_type = XtRString;
res_list->resource_size = sizeof(XtRString);
res_list->resource_offset = 0;
res_list->default_type = XtRString;
res_list->default_addr = NULL;
XtGetApplicationResources(toplevel, &res, res_list, 1, NULL, 0);
return(res);
}
/*
* determine all colors, and allocate them.
*/
static void init_colors()
{
Screen *screen = DefaultScreenOfDisplay(display);
Colormap cmap;
XColor rgb;
int i, d;
char *c, *n, class_name[256];
cmap = DefaultColormap(display, DefaultScreen(display));
for (i=0; i < NCOLS; i++) {
switch (i) {
default:
case COL_STD: n = "colStd"; d = 1; break;
case COL_RED: n = "colRedAlert"; d = 0; break;
case COL_YELLOW: n = "colYellowAlert"; d = 0; break;
case COL_GREEN: n = "colGreenAlert"; d = 0; break;
}
strcpy(class_name, n);
class_name[0] &= ~('a'^'A');
c = string_resource(n, class_name);
if (!XParseColor(display, cmap, c, &rgb))
fprintf(stderr, "%s: unknown color \"%s\" (%s)\n",
progname, c, n);
else if (!XAllocColor(display, cmap, &rgb))
fprintf(stderr, "%s: can't alloc color \"%s\" (%s)\n",
progname, c, n);
else {
color[i] = rgb.pixel;
continue;
}
color[i] = d ? BlackPixelOfScreen(screen)
: WhitePixelOfScreen(screen);
}
}